package me.numark.utils;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.util.Pair;

import java.util.LinkedHashMap;
import java.util.Map;

import me.numark.model.Dialog;
import me.numark.model.Message;
import me.numark.net.BaseResponse;
import me.numark.net.NetworkConstants;
import me.numark.providers.Numa;

/**
 * Created by Evan on 14/11/28.
 */
public class MessageUtils {

    private static volatile boolean updating = false;

    public static boolean loadMoreDialogs(ContentResolver cr, long time, long did) {
        String url = String.format(NetworkConstants.MSG_DIALOGS_URL, Global.getCurrentUid());
        Map<String, Object> params = new LinkedHashMap<String, Object>();
        params.put("did", String.valueOf(did));
//        params.put("before_time", Utils.getDatetimeStr(time));
        params.put("before_time", String.valueOf(time/1000));
        String result = HttpUtil.get(url, params);
        DialogResponse response = null;
        if (result != null) {
            try {
                response = Global.getGson().fromJson(result, DialogResponse.class);
            } catch (Exception e) {
                response = null;
            }
        }
        if (response == null || !response.ret || response.data == null) {
            return false;
        }
        if (did == 0) {
            ContentValues values = new ContentValues();
            values.put("s_int", response.timestamp * 1000);
            cr.update(Numa.KeyValueColumns.CONTENT_URI, values, "_id=0", null);
        }
        updateUnreadComments(response.unread_comments, cr);
        parseDialogs(response.data, cr);
        return true;
    }

    public static void updateUnreadComments(int num, ContentResolver cr) {
        ContentValues values = new ContentValues();
        values.put("badge", num);
        cr.update(Numa.DialogColumns.CONTENT_URI, values, "_id=0", null);
    }

    public static void asyncUpdateMsg(final Context context) {
        new Thread() {
            @Override
            public void run() {
                msgUpdate(context);
            }
        }.start();
    }

    public static boolean msgUpdate(Context context) {
        if (!Global.isLoggedIn()) {
            return false;
        }
        if (updating) {
            return false;
        }
        updating = true;
        ContentResolver cr = context.getContentResolver();
        boolean hasMore = true;
        while (hasMore) {
            long max_message_timestamp = 0;
            long max_message_id = 0;
            long max_dialog_timestamp = 0;
            long max_dialog_id = 0;
            Cursor cursor = cr
                    .query(Numa.KeyValueColumns.CONTENT_URI, new String[]{"_id", "s_int"}, "_id<2",
                            null, null);
            while (cursor.moveToNext()) {
                int cid = cursor.getInt(0);
                long value = cursor.getLong(1);
                switch (cid) {
                    case 0:
                        max_message_timestamp = value;
                        break;
                    case 1:
                        max_message_id = value;
                        break;
                }
            }
            Utils.closeQuietly(cursor);
            cursor = cr.query(Numa.DialogColumns.CONTENT_URI, new String[]{"_id", "last_time"},
                    "_id>0", null, "last_time desc limit 1");
            if (cursor.moveToFirst()) {
                max_dialog_id = cursor.getLong(0);
                max_dialog_timestamp = cursor.getLong(1);
            }
            Utils.closeQuietly(cursor);
            if (max_message_timestamp == 0) {
                loadMoreDialogs(cr, Constants.BIG_TIME, 0);
                updating = false;
                return true;
            }
            String url = String.format(NetworkConstants.MSG_UPDATE_URL, Global.getCurrentUid());
            Map<String, Object> params = new LinkedHashMap<String, Object>();
            params.put("after_did", String.valueOf(max_dialog_id));
//            params.put("after_dialog_time", Utils.getDatetimeStr(max_dialog_timestamp));
            params.put("after_dialog_time", String.valueOf(max_dialog_timestamp/1000));
            params.put("after_mid", String.valueOf(max_message_id));
//            params.put("after_msg_time", Utils.getDatetimeStr(max_message_timestamp));
            params.put("after_msg_time", String.valueOf(max_message_timestamp/1000));
            params.put("limit", "200");
            String result = HttpUtil.get(url, params);
            MsgUpdateResponse response = null;
            if (result != null) {
                try {
                    response = Global.getGson().fromJson(result, MsgUpdateResponse.class);
                } catch (Exception e) {
                    response = null;
                }
            }

            if (response == null || !response.ret) {
                updating = false;
                return false;
            }
            hasMore = response.dialog_hasmore || response.messages_hasmore;
            updateUnreadComments(response.unread_comments, cr);
            parseDialogs(response.dialogs, cr);
            Pair<Long, Long> maxPair = parseMessages(response.messages, cr);
            max_message_timestamp = maxPair.first.longValue();
            max_message_id = maxPair.second.longValue();
            if (max_message_timestamp > 0 && max_message_id > 0) {
                ContentValues values = new ContentValues();
                values.put("s_int", max_message_timestamp);
                cr.update(Numa.KeyValueColumns.CONTENT_URI, values, "_id=0", null);
                values = new ContentValues();
                values.put("s_int", max_message_id);
                cr.update(Numa.KeyValueColumns.CONTENT_URI, values, "_id=1", null);
            }
        }
        updating = false;
        return true;
    }

    public static void parseDialogs(Dialog[] data, ContentResolver cr) {
        if (data.length == 0) {
            return;
        }
        ContentValues[] contentValuesArr = new ContentValues[data.length];
        for (int i = 0; i < data.length; i++) {
            ContentValues values = new ContentValues();
            Dialog dialog = data[i];
            values.put("nick", dialog.user.nick);
            values.put("pic", dialog.user.pic);
            values.put("uid", dialog.user.uid);
            values.put("last_text", dialog.description);
            values.put("last_time", dialog.create_timestamp * 1000);
            values.put("badge", dialog.unread);
            values.put("r_status",dialog.r_status);
            values.put("_id", dialog.did);
            contentValuesArr[i] = values;
        }
        cr.bulkInsert(Numa.DialogColumns.CONTENT_URI, contentValuesArr);
    }

    public static Pair<Long, Long> parseMessages(Message[] data, ContentResolver cr) {
        long maxTime = 0;
        long maxId = 0;
        if (data.length == 0) {
            return new Pair<Long, Long>(Long.valueOf(0), Long.valueOf(0));
        }
        ContentValues[] contentValuesArr = new ContentValues[data.length];
        for (int i = 0; i < data.length; i++) {
            ContentValues values = new ContentValues();
            Message message = data[i];
            values.put("_id", message.mid);
            values.put("did", message.did);
            values.put("uid", message.uid);
            values.put("text", message.description);
            values.put("hash", message.m_hash);
            values.put("time", message.create_timestamp * 1000);
            contentValuesArr[i] = values;
            if (message.create_timestamp > maxTime) {
                maxTime = message.create_timestamp;
            }
            if (message.mid > maxId) {
                maxId = message.mid;
            }
        }
        cr.bulkInsert(Numa.MessageColumns.CONTENT_URI, contentValuesArr);
        return new Pair<Long, Long>(Long.valueOf(maxTime), Long.valueOf(maxId));
    }

    public static class DialogResponse extends BaseResponse {

        public Dialog[] data;

        public int unread_comments;
    }


    public static class MsgUpdateResponse extends BaseResponse {

        public boolean messages_hasmore;

        public boolean dialog_hasmore;

        public Dialog[] dialogs;

        public Message[] messages;

        public int unread_comments;
    }

    public static int getUnreadCount() {
        //TODO
        return 0;
    }
}
